// Copyright (c) 2010 Omer Goshen
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef COMPONENTCONTAINER_H
#define COMPONENTCONTAINER_H

#include <Ogre.h>
#include "components/Component.h"
#include "components/ComponentFactory.h"

using namespace Ogre;

class Component;

/**
 * \class ComponentContainer
 * \brief Has methods and iterators to ease ownership of Components
 */
class ComponentContainer
{
public:
	ComponentContainer() {};
	virtual ~ComponentContainer();

	/**
	 * \brief Checks if a named component already exists in this container
	 * \param componentName
	 * \return true if found
	 */
	bool hasComponent(const Ogre::String& componentName);

	/**
	 * \brief Add a pre-built Component to the container
	 * \param component
	 */
	void addComponent(Component* component);

	/**
	 * \brief Adds a Component to the container, uses ComponentFactory to instantize
	 * \param type Component type as registered in the factory
	 * \param name The instance's name
	 */
	Component* addComponent(const Ogre::String& type, const Ogre::String& name);

	/**
	 * \brief Return component by name
	 * \param componentName
	 * \return NULL if not found, the Component pointer if it was
	 */
	Component* getComponent(const Ogre::String& componentName);

	typedef std::vector<Component*> ComponentVector;
	typedef VectorIterator<ComponentVector> ComponentIterator;

	inline ComponentIterator getComponentIterator(void) { return VectorIterator<ComponentVector>(components); }

protected:
	ComponentVector components;
};

#endif
